<?php
/*-----------------------------------------------
Idea original: Bart Veraart
-----------------------------------------------*/
class zen_gtk_mysql_admin {
	/*Para crear la ventana pequeña de login:*/
	var $login_window;
	/**
	 * Contenedor vertical
	 * @var GtkVBox
	 */
	var $vbox;
	/**
	 * Contenedor horizontal
	 * @var GtkHBox
	 */
	var $hbox_top;
	/**
	 * Etiqueta superior
	 *
	 * @var GtkLabel
	 */
	var $label_top;
	/**
	 * Campo de texto superior
	 * @var GtkEntry
	 */
	var $entry_login_name;
	/**
	 * Caja de en medio
	 * @var GtkHBox
	 */
	var $hbox_middle;
	/**
	 * Etiqueta de en medio
	 * @var GtkLabel
	 */
	var $label_middle;
	/**
	 * Caja de texto de en medio para el password
	 * @var GtkEntry
	 */
	var $entry_password;
	/**
	 * Segunda contenedor en medio
	 * @var GtkHBox
	 */
	var $hbox_middle2;
	/**
	 * Segunda etiqueta de en medio para el servidor
	 * @var GtkLabel
	 */
	var $label_middle2;
	/**
	 * Segunda caja de texto en medio para el servidor
	 * @var GtkEntry
	 */
	var $entry_server;
	/**
	 * Contenedor debajo
	 * @var GtkHBox
	 */
	var $hbox_bottom;
	/**
	 * Botón para el login
	 *
	 * @var GtkButton
	 */
	var $login_button;
	/**
	 * Constructor
	 * @param str $usuario
	 * @param str $password
	 * @param str $servidor
	 *
	 * @return zen_gtk_mysql_admin
	 */
	function zen_gtk_mysql_admin($usuario="juaxix",$password="mipassword",$servidor="localhost"){
		/*Para crear la ventana pequeña de login:*/
		$this->login_window=$this->make_std_window("Login","Login");
		$this->login_window->connect('destroy','shutdown');
		$this->login_window->set_default_size(250,100);
		$this->vbox=$this->login_window->child->child;
		//Contenedor horizontal
		$this->hbox_top= &new GtkHBox(false,5);
		$this->hbox_top->set_homogeneous(true);
		//Contenedor vertical
		$this->vbox->pack_start($this->hbox_top,false,false);
		$this->hbox_top->show();
		//Etiqueta de arriba
		$this->label_top= &new GtkLabel("Usuario:");
		$this->hbox_top->pack_start($this->label_top,false,false);
		$this->label_top->show();
		//Caja de arriba
		$this->entry_login_name=&new GtkEntry();
		$this->entry_login_name->set_text($usuario);
		$this->hbox_top->pack_start($this->entry_login_name,false,false);
		$this->entry_login_name->show();
		//Caja de en medio
		$this->hbox_middle=&new GtkHBox(false,5);
		$this->hbox_middle->set_homogeneous(true);
		$this->box->pack_start($this->hbox_middle,false,false);
		$this->hbox_middle->show();
		//Etiqueta de en medio
		$this->label_middle= &new GtkLabel("Password:");
		$this->hbox_middle->pack_start($this->label_middle,false,false);
		$this->label_middle->show();
		//Caja de en medio
		$this->entry_password=&new GtkEntry();
		$this->entry_password->set_text($password);
		$this->entry_password->set_visibility(false);
		$this->hbox_middle->pack_start($this->entry_password,false,false);
		$this->entry_password->show();
		//Segunda caja de en medio para el server:
		$this->hbox_middle2=&new GtkHBox(false,5);
		$this->hbox_middle2->set_homogeneous(true);
		$this->vbox->pack_start($this->hbox_middle2,false,false);
		$this->hbox_middle2->show();
		//Segunda etiqueta de en medio
		$this->label_middle2= &new GtkLabel("Servidor:");
		$this->hbox_middle2->pack_start($this->label_middle2,false,false);
		$this->label_middle2->show();
		/*middle textfield*/
		$this->entry_server=&new GtkEntry();
		$this->entry_server->set_text($servidor);
		$this->hbox_middle2->pack_start($this->entry_server,false,false);
		$this->entry_server->show();
		//Caja de abajo
		$this->hbox_bottom=&new GtkHBox(false,5);
		$this->hbox_bottom->set_homogeneous(true);
		$this->vbox->pack_start($this->hbox_bottom,false,false);
		$this->hbox_bottom->show();
		//Botón para el login
		$this->login_button = &new GtkButton("Login");
		$this->login_button->connect("clicked","do_login",$this->entry_login_name,$this->entry_password,$this->entry_server);
		$this->hbox_bottom->pack_start($this->login_button,false,false,15);
		$this->login_window->show_all();
		gtk::main();
	}

	/**
	 * Ejecuta una consulta mySQL
	 *
	 * @param GtkButton $button
	 * @param unknown_type $query_entry
	 * @param unknown_type $dbname
	 * @param unknown_type $server
	 * @param unknown_type $name
	 * @param unknown_type $password
	 * @param unknown_type $query_combo
	 * @param unknown_type $ctree
	 */
	function exec_query($button,$query_entry,$dbname,$server,$name,$password,$query_combo,$ctree){
		/*
		execute the query: if a result is returned, show the result, if not show the affected rows
		update query logfile and refresh query_entry
		if there is an affection (after a create, alter or drop statement) refresh the tree
		*/
		global $std_title;

		$conn=mysql_connect($server,$name,$password);
		if(!$conn) alert ("connection could not be made");
		$query=$query_entry->get_text();
		mysql_select_db($dbname,$conn) or alert(mysql_error());

		$result=mysql_query($query,$conn) or alert(mysql_error());

		update_querylog($dbname,$name,$query);

		$treechange=false; /*keep track of changes made: if true-> refresh tree*/
		if($result){
			if (stristr($query,"delete")){
				alert(str_replace("delete","deleted",$query));
			}
			elseif (stristr($query,"update")) alert ("updated ".mysql_affected_rows()." records");
			elseif (stristr($query,"insert")) alert ("inserted ".mysql_affected_rows()." records");
			elseif (stristr($query,"replace")) alert ("replaced ".mysql_affected_rows()." records");
			elseif (stristr($query,"select") || stristr($query,"describe") || stristr($query,"show") || stristr($query,"explain")){
				$window=$this->make_std_window($std_title."query result","result");
				$vbox=$window->child->child;
				$vbox->set_homogeneous(false);
				$query_label=&new Gtklabel("Query: \n$query \nreturned ".mysql_num_rows($result)." rows.");

				$query_label->set_line_wrap(true);
				$vbox->pack_start($query_label,false,false);
				$query_label->show();

				$scroll_window=&new GtkScrolledWindow();
				$scroll_window->set_border_width(5);
				$scroll_window->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
				$vbox->pack_start($scroll_window,true,true);

				for($i=0;$i<mysql_num_fields($result);$i++){
					$field_names[$i]=mysql_field_name($result,$i);
				}

				$clist=&new GtkClist(mysql_num_fields($result),$field_names);

				$scroll_window->add($clist);
				$clist->show();

				for($i=0;$i<mysql_num_rows($result);$i++){
					$col=$clist->append(mysql_fetch_row($result));
					$clist->set_column_auto_resize($col,true);
				}

				$window->show_all();
			}

			else if (stristr($query,"drop")) {
				$treechange=true;
				alert(str_replace("drop","dropped",$query));
			}

			else if (stristr($query,"alter")) {
				$treechange=true;
				alert(str_replace("alter","altered",$query));
			}

			else if (stristr($query,"create")) {
				$treechange=true;
				alert(str_replace("create","created",$query));
			}
		}
		mysql_close($conn);

		if($treechange==true) {
			$tbl_str="table";
			$tbl_strp=strpos($query,$tbl_str);

			$affected_table=substr($query,$tbl_strp+strlen($tbl_str)+1);
			$pos=strpos($affected_table," ");
			$affected_table=substr($affected_table,0,$pos);
			//alert("affected tabel: ".$affected_table);
		}

		if ($treechange==true) refresh_ctree($ctree,$dbname,$server,$name,$password,$affected_table);
		refresh_query_combo($query_combo,$dbname,$name);
	}

	/*function selectrow($var){
	alert("select row");
	}*/

	function do_login($button,$entry_login_name,$entry_password,$entry_server){
		global $std_title;

		$name=$entry_login_name->get_text();
		$passwd=$entry_password->get_text();
		$server=$entry_server->get_text();

		$conn=mysql_connect($server,$name,$passwd);
		if(!$conn)
		alert("could not connect $name to mysql-server $server!\n".mysql_error());

		else {
			$rs_dbs=mysql_list_dbs($conn);

			/*create a standard window and get the vbox*/

			$data_window= new GtkWindow();
			$data_window->connect("destroy","close_window");
			$data_window->connect("delete_event","delete_event");
			$data_window->set_title($std_title." ".$server);
			$data_window->set_default_size(500,500);

			$data_window_vbox= &new GtkVBox();

			$data_window->add($data_window_vbox);
			$data_window_vbox->show();

			$notebook= new GtkNotebook();
			$notebook->show();

			$notebook->set_tab_pos(GTK_POS_LEFT);
			$notebook->set_scrollable(true);

			$data_window_vbox->pack_start($notebook,true,true,0);

			$notebook->set_border_width(10);
			$notebook->realize();

			/*create the pages behind the tabs*/
			for($i=0;$i<mysql_num_rows($rs_dbs);$i++){
				$row=mysql_fetch_object($rs_dbs);

				$frame= &new GtkFrame($row->Database);

				$vbox = &new GtkVBox(true, 0);
				$vbox->set_homogeneous(false);
				$frame->add($vbox);
				$hbox = &new GtkHbox(true, 0);
				$vbox->pack_start($hbox, true, true);


				$rs_tables=mysql_list_tables($row->Database);

				/*a nice scrolling window*/
				$scroll_window=&new GtkScrolledWindow();
				$scroll_window->set_border_width(5);
				$scroll_window->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
				$hbox->pack_start($scroll_window,false,true);

				$ctree=&new GtkCTree(2, 0, array('Table','Type'));
				$scroll_window->add($ctree);
				$ctree->show();

				$ctree->set_column_auto_resize(0, true);
				$ctree->set_column_width(1, 200);
				$ctree->set_selection_mode(GTK_SELECTION_EXTENDED);
				$ctree->set_line_style(GTK_CTREE_LINES_SOLID);

				/*main tree*/

				refresh_ctree($ctree,$row->Database,$server,$name,$passwd);

				$query_hbox=&new GtkHBox();
				$vbox->pack_start($query_hbox,false,false);

				$query_hbox->show();

				$query_label= &new GtkLabel("Query:  ");
				$query_hbox->pack_start($query_label,false,false);
				$query_label->show();

				$query_history="";
				$handle=fopen("query.log","r")or alert ("Could not open query logfile");
				while(!feof($handle)){
					$query_log_line=fgets($handle,4096);
					$query_log_line_array=explode(":",$query_log_line);
					if($query_log_line_array[0]==$row->Database && $query_log_line_array[1]==$name)
					$query_history[]=trim($query_log_line_array[2]);
				}

				$query_combo= &new GtkCombo();

				$query_combo->set_popdown_strings($query_history);
				$query_entry = $query_combo->entry;
				$query_entry->set_text('');
				$query_entry->set_max_length(5000);
				$query_entry->select_region(0, -1);
				$query_hbox->pack_start($query_combo,true,true);
				$query_combo->show();

				//$ctree->connect('select-row','selectrow',$query_entry);

				$query_button=&new GtkButton("GO!!");
				$query_button->connect('clicked','exec_query',$query_entry,$row->Database,$server,$name,$passwd,$query_combo,$ctree);
				$query_hbox->pack_start($query_button,false,false);
				$query_button->show();

				$frame->show_all();

				$label_box = &new GtkHBox(false, 0);

				$label = &new GtkLabel($row->Database);
				$label_box->pack_start($label, false, true, 0);
				$label_box->show_all();

				$menu_box = &new GtkHBox(false, 0);

				$label = &new GtkLabel($row->Database);
				$menu_box->pack_start($label, false, true, 0);
				$menu_box->show_all();

				$notebook->append_page_menu($frame, $label_box, $menu_box);
			}

			$data_window->show();
			mysql_close($conn);
		}
	}
	function delete_event(){
		return false;
	}

	function close_window($widget){
		$window = $widget->get_toplevel();
		$window->hide();
	}

	function shutdown(){
		print("Shutting down...\n");
		gtk::main_quit();
	}

	function alert($string){

		$string=wordwrap($string,30);
		$dialog = &new GtkDialog();
		$dialog->set_policy(true, false, false);
		$dialog->set_position(GTK_WIN_POS_CENTER);
		//$dialog->connect_object("destroy","close_window");

		$dialog_vbox = $dialog->vbox;
		$dialog_action_area = $dialog->action_area;

		$user_info_label = &new GtkLabel($string);
		$dialog_vbox->pack_start($user_info_label);

		$ok_button = &new GtkButton("OK");
		$ok_button->connect("clicked","close_window");
		$dialog_action_area->pack_start($ok_button);

		$dialog->show_all();
	}

	function make_std_window($window_title,$frame_title){
		global $std_title;
		$window= &new GtkWindow();
		$window->set_default_size(700,500);
		$window->connect("destroy","close_window");
		$window->connect("delete_event","delete_event");
		$window->set_title($std_title." ".$window_title);

		$frame=&new GtkFrame($frame_title);
		$window->add($frame);
		$frame->show();

		$vbox= &new GtkVBox();
		$vbox->set_homogeneous(false);
		$frame->add($vbox);
		$vbox->show();

		return $window;
	}

	function update_querylog($dbname,$name,$query){
		if(!exist_in_log("$dbname:$name:$query")){
			if(!$handle=fopen("query.log","a+")){
				alert ("Could not open querylogfile for writing");
				return false;
			}
			else fputs($handle,"$dbname:$name:$query\n");
		}
		fclose($handle);
	}

	function exist_in_log($line){
		/*does a certain line exist in the query log?*/
		if(file_exists("query.log")){
			if(!$handle=fopen("query.log","r")) alert ("Could not open querylogfile for reading");
			else {
				while(!feof($handle)){
					$logline=fgets($handle,4096);
					if(strcmp(trim($logline),trim($line))==0) return true;
				}
				fclose($handle);
			}
		}
		else alert("Querylogfile does not exist");
		return false;
	}

	function clear_log (){
		/*truncate the querylogfile if it exists*/
		if(file_exists("query.log")) alert ("No querylogfile exists");
		else $handle=fopen("query.log","w");
		fclose($handle);
	}

	function confirm($string){
		$dialog = &new GtkDialog();
		$dialog->set_policy(true, false, false);
		$dialog->set_position(GTK_WIN_POS_CENTER);
		//$dialog->connect_object("destroy","close_window");

		$dialog_vbox = $dialog->vbox;
		$dialog_action_area = $dialog->action_area;

		$user_info_label = &new GtkLabel($string);
		$dialog_vbox->pack_start($user_info_label);

		$ok_button = &new GtkButton("OK");
		$ok_button->connect("clicked","return_true");
		$dialog_action_area->pack_start($ok_button);

		$cancel_button= &new GtkButton("Cancel");
		$cancel_button->connect("clicked","return_false");
		$dialog_action_area->pack_start($cancel_button);

		$dialog->show_all();
	}


	function refresh_query_combo($query_combo,$db,$name){
		$query_history="";
		$handle=fopen("zen_mysql_consultas.log","r")or alert ("No se puede abrir el fichero zen_mysql_consultas.log");
		while(!feof($handle)){
			$query_log_line=fgets($handle,255);
			$query_log_line_array=explode(":",$query_log_line);
			if($query_log_line_array[0]==$db && $query_log_line_array[1]==$name)
			$query_history[]=trim($query_log_line_array[2]);
		}
		//$query_history=reverse_array($query_history);
		$query_history=array_reverse($query_history);
		$query_combo->set_popdown_strings($query_history);
	}


	function refresh_ctree($ctree,$db,$server,$user,$passwd,$affected_tablename){
		$conn=mysql_connect($server,$user,$passwd);
		mysql_select_db($db);

		$rs_tables=mysql_list_tables($db);

		$ctree->freeze();
		$ctree->clear();

		for($j=0;$j<mysql_num_rows($rs_tables);$j++){
			$tablename=mysql_tablename($rs_tables,$j);

			$tablename_array=array($tablename,'');
			$parent=$ctree->insert_node(null,null,$tablename_array,5,null,null,null,null,false,false);

			$rs_field=mysql_list_fields($db,$tablename,$conn);

			for($k=0;$k<mysql_num_fields($rs_field);$k++){
				$field=mysql_field_name($rs_field,$k);
				$field_array=array($field,mysql_field_type($rs_field,$k)."(".mysql_field_len($rs_field,$k).") ".mysql_field_flags($rs_field,$k));

				$ctree->insert_node($parent,null,$field_array,5,null,null,null,null,true,false);
			}
			if($tablename==$affected_tablename) $ctree->expand($parent);
		}

		$ctree->thaw();
	}

	function return_true(){
		return true;
	}

	function return_false(){
		return false;
	}

}
?>